#include "MyW25Q64.h"





//初始化W25164
//无参
//无返回值
void MyW25Q64_Init(void)
{
	//开启SPI CS引脚时钟
	rcu_periph_clock_enable(W25Q64_RCU_GPIOX);
	//配置SPI CS引脚模式
	gpio_mode_set(W25Q64_GPIOX,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,W25Q64_GPIO_PIN);
	gpio_output_options_set(W25Q64_GPIOX,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,W25Q64_GPIO_PIN);
	//拉高CS，未选中状态
	W25Q64_DISABLE();
	//初始化SPI
	MySpi_init();
}


//等待W25Q64上一次操作完成
//无参
//无返回值
void MyW25Q64_WaitBusy(void)
{
	//定义接收缓存
	uint8_t rdata;
	//循环判断Busy状态位
	do
	{
		//拉低CS
		W25Q64_ENABLE();
		//发送命令字，读取W25Q64状态
		MySpi_ReadWriteByte(0x05);
		//接收状态寄存器值
		rdata = MySpi_ReadWriteByte(0xff);
		//拉高CS
		W25Q64_DISABLE();
	}while(rdata & 0x01);
}

//写使能W25Q64
//无参
//无返回值
void MyW25Q64_WriteEnable(void)
{
	//等待上一次操作完成
	MyW25Q64_WaitBusy();
	//拉低CS
	W25Q64_ENABLE();
	//发送写使能命令字
	MySpi_ReadWriteByte(0x06);
	//拉高CS
	W25Q64_DISABLE();
}

//写失能W25Q64
//无参
//无返回值
void MyW25Q64_WriteDisable(void)
{
	//等待上一次操作完成
	MyW25Q64_WaitBusy();
	//拉低CS
	W25Q64_ENABLE();
	//发送写失能命令字
	MySpi_ReadWriteByte(0x04);
	//拉高CS
	W25Q64_DISABLE();
}


//擦除64K内容
//参数：xblock  要擦除的块
//无返回值
void MyW25Q64_Erase64K(uint8_t xblock)
{
	uint8_t wdata[4];
	//存储64k擦除命令字
	wdata[0]=0xD8;
	//存储要擦除的页的地址
	wdata[1]=(xblock*64*1024)>>16;
	wdata[2]=(xblock*64*1024)>>8;
	wdata[3]=(xblock*64*1024)>>0;
	//等待上一次操作完成
	MyW25Q64_WaitBusy();
	//写使能
	MyW25Q64_WriteEnable();
	//拉低CS
	W25Q64_ENABLE();
	//发送擦除命令
	MySpi_Write(wdata,4);
	//拉高CS
	W25Q64_DISABLE();
	//等待上一次操作完成
	MyW25Q64_WaitBusy();
	printf("擦除%x%x%x完成\r\n",wdata[1],wdata[2],wdata[3]);
}

//按页写入（一页256字节）
//参数：wbuffer  要写入的数组
//参数：xpage  	 要写入的页
//无返回值
void MyW25Q64_PageWrite(uint8_t* wbuffer,uint16_t xpage)
{
	uint8_t wdata[4];
	//存储页写入命令
	wdata[0]=0x02;
	//存储要写入的页的地址
	wdata[1]=(xpage*256)>>16;
	wdata[2]=(xpage*256)>>8;
	wdata[3]=(xpage*256)>>0;
	printf("%d\r\n",wbuffer[0]);
	printf("xpage%d\r\n",xpage);
	//等待上一次操作完成
	MyW25Q64_WaitBusy();
	//写使能
	MyW25Q64_WriteEnable();
	//拉低CS
	W25Q64_ENABLE();
	//发送写入命令
	MySpi_Write(wdata,4);
	//发送要写入的数组
	MySpi_Write(wbuffer,256);
	//拉高CS
	W25Q64_DISABLE();
}

//按页读取（一页256字节）
//参数：rbuffer  读取数据存放的数组
//参数：addr  	 数据的首地址
//参数：datalen  	 数据的长度
//无返回值
void MyW25Q64_Read(uint8_t* rbuffer,uint32_t addr,uint32_t datalen)
{
	uint8_t wdata[4];
	//存储读取命令
	wdata[0]=0x03;
	//存储要读取的数据的地址
	wdata[1]= addr>>16;
	wdata[2]= addr>>8;
	wdata[3]= addr>>0;
	//等待上一次操作完成
	MyW25Q64_WaitBusy();
	//拉低CS
	W25Q64_ENABLE();
	//发送读取命令
	MySpi_Write(wdata,4);
	//接受数据
	MySpi_Read(rbuffer,datalen);
	//拉高CS
	W25Q64_DISABLE();
}



